#lang racket


(provide 
 display-port
 
 process-in
 process-out
 process-error
 process-fn
 
 svn-process
 
 svn-update
 svn-export)


; io

(define (display-port port)
  (let ((l (read-line port 'any)))
    (cond ((eof-object? l)
           (void))
          (else
           (write-string l)
           (newline)
           (display-port port)))))


; process

(define (process-in proc)
  (second proc))

(define (process-out proc)
  (first proc))

(define (process-error proc)
  (fourth proc))

(define (process-fn proc)
  (fifth proc))


(define (svn-process command fn)
  (let ((proc (process command)))
    (let ((proc-in (process-in proc))
          (proc-out (process-out proc))
          (proc-error (process-error proc))
          (proc-fn (process-fn proc)))
      (fn proc-in proc-out proc-error proc-fn)
      (close-output-port proc-in)
      (close-input-port proc-out)
      (close-input-port proc-error))))


; svn update

(define (svn-update-command update-path)
  (format "svn update ~A" update-path))

(define (svn-update-fn in out error fn)
  (display-port out)
  (display-port error))

(define (svn-update update-path)
  (svn-process (svn-update-command update-path) svn-update-fn))


; svn export

(define (svn-export-command source-url/path export-path)
  (let ((source-str
         (if (path? source-url/path)
             (path->string source-url/path)
             source-url/path))
        (export-str
         (if (path? export-path)
             (path->string export-path)
             export-path)))
    (format "svn export ~A ~A" source-str export-str)))

(define (svn-export-fn in out error fn)
  (display-port out)
  (display-port error))

(define (svn-export source-url/path export-path)
  (svn-process (svn-export-command source-url/path export-path) svn-export-fn))